package com.mdd.common.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import com.alibaba.fastjson2.JSONObject;
import com.mdd.common.plugin.wechat.WxMnpDriver;
import com.mdd.common.service.WxCommonService;
import com.mdd.common.wechat.utils.WxConstants;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class WxCommonServiceImpl implements WxCommonService {


    @Value("${ym.envVersion}")
    private String envVersion;

    @Override
    public String generateMiniCode(String scene, String page) {
        WxMaService mnp = WxMnpDriver.mnp();
        PrintWriter out = null;
        InputStream in = null;
        try {
            String accessToken = mnp.getAccessToken();
            String requestUrl = String.format(WxConstants.get_unlimited_qr_code, accessToken);
            URL realUrl = new URL(requestUrl);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            Map<String, Integer> color = new HashMap<String, Integer>() {{
                put("r", 9);
                put("g", 56);
                put("b", 148);
            }};
            JSONObject params = new JSONObject();
            // params.put("path", "pages/store/payInfo?storeId=" + storeId+"&channel=2");
            params.put("page", page);
            params.put("scene", scene);
            params.put("check_path", false);

            params.put("auto_color", false);
            params.put("line_color", color);
            // 小程序版本
            params.put("env_version", envVersion);
            params.put("width", 600);
            out.write(params.toString());
            // 发送请求参数,利用connection的输出流，去写数据到connection中，我的参数数据流出我的电脑内存到connection中，让connection把参数帮我传到URL中去请求。
            out.print(requestUrl);

            // flush输出流的缓冲
            out.flush();
            // 获取URL的connection中的输入流，这个输入流就是我请求的url返回的数据,返回的数据在这个输入流中，流入我内存，我将从此流中读取数据
            in = conn.getInputStream();
            // 定义个空字节数组
            byte[] data = null;
            // 读取图片字节数组
            try {
                // 创建字节数组输出流作为中转仓库，等待被写入数据
                ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
                byte[] buff = new byte[100];
                int rc = 0;
                while ((rc = in.read(buff, 0, 100)) > 0) {
                    // 向中转的输出流循环写出输入流中的数据
                    swapStream.write(buff, 0, rc);
                }
                // 此时connection的输入流返回给我们的请求结果数据已经被完全地写入了我们定义的中转输出流swapStream中
                data = swapStream.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            String base64Code = new String(Objects.requireNonNull(Base64.encodeBase64(data)));
            // Base64转byte[]数组
            return base64Code;
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return "";
    }
}
